<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/9 0009
 * Time: 下午 3:16
 */
namespace app\common\service;

use app\common\BaseHelper;
use app\common\DictConstant;
use think\Cache;
use think\Controller;
use app\admin\model\Tenant;
use app\admin\model\Miniprogramtemplate;

/**
 * 微信小程序助手类
 * Class MiniProgramHelp
 * @package backend\components
 */
class MiniProgramHelp extends Controller{

    /**
     * 生成第三方授权二维码链接
     * @return string
     * @author fei <xliang.fei@gmail.com>
     */
    public static function createAuthCode(){
        $pre_auth_code = self::getPreAuthCode();
        if(empty($pre_auth_code)){
            exit("授权失败");
        }
        $AppId = config('miniprogram.MiaoDaoOpenAppID');
        //halt($AppId);
        $redirect_uri = config('miniprogram.domain').'/wx/authcodecallback?b='.session('TENANT_ID');
        return 'https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=' . $AppId . '&pre_auth_code=' . $pre_auth_code . '&redirect_uri=' . $redirect_uri;
    }


    /**
     * 获取预授权码pre_auth_code
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getPreAuthCode(){
        $token = Cache::get('MiaoDaoOpenPreAuthCode');
        if(!empty($token)){
            $token = json_decode($token, true);
            if (!empty($token['expires_time']) && !empty($token['component_access_token']) && time() <= $token['expires_time']) {
                return $token['component_access_token'];
            }
        }
        $component_access_token = self::getCompomentAccessToken();
        if (empty($component_access_token)) {
            return false;
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=' . $component_access_token;
        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $result = json_decode(BaseHelper::curlPost($url,json_encode($postData)),true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '获取预授权码pre_auth_code');

        //令牌
        $data['pre_auth_code'] = $result['pre_auth_code'];
        //过期时间(20分钟)
        $data['expires_time'] = time() + 20 * 60;

        Cache::set('MiaoDaoOpenPreAuthCode',json_encode($data),$data['expires_time']);
        return $data['pre_auth_code'];
    }


    /**
     * 获取第三方平台component_access_token(接口调用凭据)
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getCompomentAccessToken(){
        //先从缓存里面读取token，看有没有过期
        $token = Cache::get('MiaoDaoOpenComponentAccessToken');
        if(!empty($token)){
            $token = json_decode($token, true);
            if(!empty($token['expires_time']) && !empty($token['component_access_token']) && time()<$token['expires_time']){
                return $token['component_access_token'];
            }
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $postData['component_appsecret'] = config('miniprogram.MiaoDaoOpenAppSecret');
        $path = APP_PATH . 'ticket/cache/MiaoDaoOpenVerifyTicket.php';
        $postData['component_verify_ticket'] = file_get_contents($path);
        $result = json_decode(BaseHelper::curlPost($url,json_encode($postData)),true);
        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '获取第三方平台component_access_token');

        if (empty($result['component_access_token'])) {
            return false;
        }
        //令牌
        $data['component_access_token'] = $result['component_access_token'];
        //过期时间(1小时50分钟)
        $data['expires_time'] = time() + 60 * 60 + 50 * 60;
        Cache::set('MiaoDaoOpenComponentAccessToken',json_encode($data),$data['expires_time']);

        return $data['component_access_token'];
    }


    /**
     * 使用授权码换取公众号或小程序的接口调用凭据和授权信息
     * @param $auth_code
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getApiQueryAuth($auth_code)
    {
        //接口调用凭据
        $component_access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=' . $component_access_token;

        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $postData['authorization_code'] = $auth_code;

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '使用授权码换取公众号或小程序的接口调用凭据和授权信息');

        return $result;
    }

    /**
     * 获取授权方令牌
     * @param   string $businessId 商家id
     * @param   bool $isRefresh 是否刷新token
     * @return bool|string
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getAuthorizerToken($businessId, $isRefresh = false)
    {
        $businessMiniProgram = Tenant::get($businessId);

        if (empty($businessMiniProgram)) {
            self::saveMiniProgramLog('', '', '', '获取授权方令牌接口 商家小程序信息为空 businessId:' . $businessId);
            return false;
        }

        //未过期
        if (empty($isRefresh) && time() < strtotime($businessMiniProgram->authorizerAccessTokenExpires)) {
            return $businessMiniProgram->authorizerAccessToken;
        }

        //接口调用凭据
        $component_access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=' . $component_access_token;

        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $postData['authorizer_appid'] = $businessMiniProgram->appId;
        $postData['authorizer_refresh_token'] = $businessMiniProgram->authorizerRefreshToken;
        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '获取授权方令牌 businessId:' . $businessId);

        if (empty($result['authorizer_access_token'])) {
            return false;
        }


        $businessMiniProgram->authorizerAccessToken = $result['authorizer_access_token'];
        $businessMiniProgram->authorizerAccessTokenExpires = date('Y-m-d H:i:s', time() + 55 * 60 * 2);
        $businessMiniProgram->authorizerRefreshToken = $result['authorizer_refresh_token'];

        if ($businessMiniProgram->save()) {
            return $result['authorizer_access_token'];
        } else {
            return false;
        }
    }


    /**
     * 获取授权方的帐号基本信息
     * @param $businessId
     * @return bool
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getAuthorizerInfo($businessId)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }

        //接口调用凭据
        $component_access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=' . $component_access_token;

        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $postData['authorizer_appid'] = $businessMiniProgram->appId;

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '获取授权方的帐号基本信息 businessId:' . $businessId);

        return $result;
    }

    /**
     * 获取小程序体验二维码
     * @param $businessId
     * @return bool|mixed
     */
    public static function getQrcode($businessId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/get_qrcode?access_token=' . $access_token;
        //记录日志
        //self::saveMiniProgramLog($url, '', $result, '获取体验小程序的体验二维码 businessId:' . $businessId);
        return $url;
    }

    /**
     * 生成店铺二维码
     * @param $businessId
     * @param $storeId
     * @return bool|mixed
     */
    public static function getStoreCode($businessId,$storeId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        //接口调用凭据
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token;
        $postData["scene"] = $storeId;
        $postData["path"] = "pages/home/Home";

        $result = BaseHelper::curlPost($url,json_encode($postData));
        if(json_decode($result,true)['errcode']){

            return false;
        }
        $upload = config('path.Upload_path');
        $filepath = config('path.storeQrcode') . BaseHelper::getUUID().'.png';
        file_put_contents($upload.$filepath,$result);
        return $filepath;
    }

    /**
     * 生成商品二维码
     */
    public static function getProductQrcode($businessId, $productId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        //接口调用凭据
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token;
        $postData["scene"] = $productId;
        //$postData["path"] = "pages/home/Home";
        $postData["page"] = "pages/product/ProductDetails";

        $result = BaseHelper::curlPost($url,json_encode($postData));
        if(json_decode($result,true)['errcode']){
            return false;
        }
        $upload = config('path.Upload_path');
        $filepath = config('path.storeQrcode') . BaseHelper::getUUID().'.png';
        file_put_contents($upload.$filepath, $result);

        return $filepath;
    }

    /**
     * 记录请求
     * @param $url  string  请求地址
     * @param $request  array   请求数据
     * @param $response array   返回数据
     * @param $msg  string  备注信息
     * @author fei <xliang.fei@gmail.com>
     */
    public static function saveMiniProgramLog($url, $request, $response, $msg = '')
    {
        file_put_contents(config('path.MiniProgramLog'), '发起时间：' . date('Y-m-d H:i:s') . $msg . ' 请求地址Url:' . $url . ' 请求数据：' . json_encode($request) . ' 返回数据：' . json_encode($response) . PHP_EOL);
    }


    /**
     * 获取授权小程序帐号的可选类目
     * @param $businessId
     * @return bool|mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getCategory($businessId)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }

        //接口调用凭据
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/get_category?access_token=' . $access_token;

        $result = json_decode(BaseHelper::curlGet($url), true);

        //记录日志
        self::saveMiniProgramLog($url, '', $result, '获取授权小程序帐号的可选类目 businessId:' . $businessId);

        return $result;
    }

    /**
     * 获取小程序的第三方提交代码的页面配置
     * @param $businessId
     * @return bool|mixed
     */
    public static function getAddress($businessId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/get_page?access_token=' . $access_token;
        $result = json_decode(BaseHelper::curlGet($url), true);
        //记录日志
        self::saveMiniProgramLog($url, '', $result, '获取小程序的第三方提交代码的页面配置 businessId:' . $businessId);
        return $result;
    }


    /**
     * 修改服务器地址(需要先将域名登记到第三方平台的小程序服务器域名中，才可以调用接口进行配置)
     * @param $businessId
     * @param $action
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function modifyDomain($businessId, $action = 'add')
    {
        $access_token = self::getAuthorizerToken($businessId);           //接口调用凭据
        $url = 'https://api.weixin.qq.com/wxa/modify_domain?access_token=' . $access_token;
        $postData['action'] = $action;
        $postData['requestdomain'] = [config('miniprogram.MiaoDaoOpenRequestdomain')];
        $postData['wsrequestdomain'] = [config('miniprogram.MiaoDaoOpenRequestdomain')];
        $postData['uploaddomain'] = [config('miniprogram.MiaoDaoOpenRequestdomain')];
        $postData['downloaddomain'] = [config('miniprogram.MiaoDaoOpenRequestdomain')];

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '修改服务器地址 businessId:' . $businessId);

        return $result;
    }

    /**
     * 为授权的小程序帐号上传小程序代码
     * @param $businessId
     * @param $templateId  string 指定提交模板id
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function commitCode($businessId, $templateId,$user_version,$user_desc)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }

        $access_token = self::getAuthorizerToken($businessId);           //接口调用凭据
        $url = 'https://api.weixin.qq.com/wxa/commit?access_token=' . $access_token;

//        //小程序模板信息
//        $MiniprogramtemplateModel = new Miniprogramtemplate();
//        $miniProgramTemplate = $MiniprogramtemplateModel->where(['businessId' => $businessId, 'status' => 10])->find();
//        if (empty($miniProgramTemplate)) {
//            //记录日志
//            self::saveMiniProgramLog($url, '', '', '模板信息不存在 businessId:' . $businessId . ' templateId:' . $businessMiniProgram->templateId);
//            return false;
//        }

        $postData['template_id'] = $templateId;
        $postData['ext_json'] = json_encode([
            'extAppid' => $businessMiniProgram->appId,
            'ext' => [
                  'appId' => $businessMiniProgram->appId,
                  'businessId' => $businessId,

//                'mchId' => $businessMiniProgram->mchId,
//                'partnerKey' => $businessMiniProgram->partnerKey
            ],
            'extPages' => '',
//            'pages' => ["pages/index/index", "pages/logs/logs"],
            'window' => '',
            'networkTimeout' => '',
            'tabBar' => '',
        ]);
        $postData['user_version'] = $user_version;
        $postData['user_desc'] = $user_desc;

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE)), true);

        $result['versions'] = $postData['user_version'];
        $result['templateId'] = $postData['template_id'];

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '为授权的小程序帐号上传小程序代码 businessId:' . $businessId . (!empty($templateId) ? " 指定更新模板ID:" . $templateId : ""));

        return $result;
    }

    /**
     * 将第三方提交的代码包提交审核
     * @param $businessId
     * @return bool|mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function submitAuditCode($businessId,$postdata)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }



        //获取授权小程序分类
        $categoryResult = self::getCategory($businessId);
        if (empty($categoryResult['category_list'][0])) {
            return false;
        }

        //获取小程序的页面配置
        $addressResult = self::getAddress($businessId);
        if(empty($addressResult['page_list'])){
            return false;
        }


        $access_token = self::getAuthorizerToken($businessId);           //接口调用凭据
        $url = 'https://api.weixin.qq.com/wxa/submit_audit?access_token=' . $access_token;

        $postData['item_list'] = [
            [
                "address" => $addressResult['page_list'][0],
                "tag" => $postdata['tag'],
                "first_class" => $categoryResult['category_list'][0]['first_class'],
                "second_class" => $categoryResult['category_list'][0]['second_class'],
                'first_id' => $categoryResult['category_list'][0]['first_id'],
                'second_id' => $categoryResult['category_list'][0]['second_id'],
                "title" => "首页"
            ]
        ];

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '将第三方提交的代码包提交审核 businessId:' . $businessId);

        return $result;
    }


    /**
     * 获取第三方提交的审核版本的审核状态
     * @param $businessId
     * @return bool|mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function getAuditStatus($businessId)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }

        $access_token = self::getAuthorizerToken($businessId);           //接口调用凭据

        $url = 'https://api.weixin.qq.com/wxa/get_auditstatus?access_token=' . $access_token;

        $postData['auditid'] = $businessMiniProgram->auditid;

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE)), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '获取第三方提交的审核版本的审核状态 businessId:' . $businessId);

        return $result;
    }

    /**
     * 发布已通过审核的小程序
     * @param $businessId
     * @return bool|mixed
     * @author fei <xliang.fei@gmail.com>
     */
    public static function releaseCode($businessId)
    {
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }

        $access_token = self::getAuthorizerToken($businessId);           //接口调用凭据
        $url = 'https://api.weixin.qq.com/wxa/release?access_token=' . $access_token;

        $postData = '{}';

        $result = json_decode(BaseHelper::curlPost($url, $postData), true);

        //记录日志
        self::saveMiniProgramLog($url, $postData, $result, '发布已通过审核的小程序 businessId:' . $businessId);

        return $result;
    }

    /**
     * 获取第三方平台草稿箱中的模板
     * @param $businessId
     * @return bool|mixed
     */
    public static function getTemplateDrafts($businessId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/gettemplatedraftlist?access_token=' . $access_token;
        $result = json_decode(BaseHelper::curlGet($url),true);
        //记录日志
        self::saveMiniProgramLog($url, '', $result, '获取开放平台草稿箱模板 businessId:' . $businessId);
        return $result;
    }

    /**
     * 把草稿箱的模板添加到模板库
     * @param $businessId
     * @param $draft_id
     * @return bool|mixed
     */
    public static function pushDraftsToTemplate($businessId,$draft_id){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/addtotemplate?access_token=' . $access_token;

        $result = json_decode(BaseHelper::curlPost($url,json_encode($draft_id,JSON_UNESCAPED_UNICODE)),true);
        //记录日志
        self::saveMiniProgramLog($url, "", $result, '将草稿箱添加到模板库 businessId:' . $businessId);
        return $result;
    }

    /**
     * 获取开放平台模板库
     * @param $businessId
     * @return bool|mixed
     */
    public static function getTemplateList($businessId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/gettemplatelist?access_token=' . $access_token;
        $result = json_decode(BaseHelper::curlGet($url),true);
        //记录日志
        self::saveMiniProgramLog($url, '', $result, '获取开放平台小程序模板库 businessId:' . $businessId);
        return $result;
    }

    /**
     * 删除开放平台小程序模板
     * @param $businessId
     * @param $template_id
     * @return bool|mixed
     */
    public static function DelTemplate($businessId,$template_id){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getCompomentAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/deletetemplate?access_token=' . $access_token;
        $result = json_decode(BaseHelper::curlPost($url,json_encode($template_id,JSON_UNESCAPED_UNICODE)),true);
        self::saveMiniProgramLog($url, "", $result, '删除模板 businessId:' . $businessId);
        return $result;
    }

    public static function GetExperiencerList($businessId){
        $businessMiniProgram = Tenant::get($businessId);
        if (empty($businessMiniProgram)) {
            return false;
        }
        $access_token = self::getAuthorizerToken($businessId);
        $url = 'https://api.weixin.qq.com/wxa/memberauth?access_token=' . $access_token;
        $postdata['action'] = "get_experiencer";
        $result = json_decode(BaseHelper::curlPost($url,json_encode($postdata,JSON_UNESCAPED_UNICODE)),true);
        self::saveMiniProgramLog($url, "", $result, '获取体验成员 businessId:' . $businessId);
        return $result;
    }


    /**
     * 添加小程序体验者
     * @param $manageId
     * @param $wechatid
     * @return mixed
     */
    public static function AddWechatExperiencer($manageId,$wechatid){
        $access_token = self::getAuthorizerToken($manageId);
        $url = 'https://api.weixin.qq.com/wxa/bind_tester?access_token=' . $access_token;
        $postdata['wechatid'] = $wechatid;

        $result = json_decode(BaseHelper::curlPost($url,json_encode($postdata,JSON_UNESCAPED_UNICODE)),true);
        return $result;

    }
}